package com.csaba.swing.gui;

import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.StringTokenizer;
import java.util.logging.Logger;

import javax.swing.ImageIcon;

import com.csaba.connector.model.Customer;
import com.csaba.connector.model.Session;
import com.csaba.swing.MainWindow;
import com.csaba.util.LoggerHelper;

public class GUIContext
{
	private final static Logger logger = LoggerHelper.getDefaultLogger();

	//singleton
	private final static GUIContext instance = new GUIContext();

	public final static GUIContext getInstance()
	{
		return instance;
	}

	private ArrayList<ContextListener> contextListeners;

	private final ArrayList<Session> sessions = new ArrayList<Session>();

	public void addContextListener( final ContextListener listener )
	{
		if ( contextListeners == null )
			contextListeners = new ArrayList<ContextListener>();

		if ( !contextListeners.contains(listener) )
		{
			contextListeners.add(listener);
		}
	}

	public void removeContextListener( final ContextListener listener )
	{
		if ( contextListeners == null )
			return;
		contextListeners.remove(listener);
	}

	private void fireContextEvent( final int eventType )
	{
		if ( contextListeners == null )
			return;

		for ( final ContextListener listener : contextListeners )
		{
			listener.contextEventPerformed(eventType);
		}
	}

	public Session getSession( final Customer customer )
	{
		for ( final Session session : sessions )
		{
			if ( session.getCustomer().equals(customer) )
				return session;
		}
		return null;
	}

	@SuppressWarnings( "unchecked" )
	public List<Session> getSessions()
	{
		return (List<Session>) sessions.clone();
	}

	public void addSession( final Session session )
	{
		if ( sessions.contains(session) )
		{
			logger.warning("Session has been already added: " + session.getSessionId()); //$NON-NLS-1$
			return;
		}

		MainWindow.getStatusBar().setMessage(
				MainWindow.getString("GUIContext.msg.loggedIn", session.getBank().getName())); //$NON-NLS-1$
		MainWindow.getStatusBar().setOnline(true);
		sessions.add(session);
		logger.info("Session is added: " + session.getSessionId() + " / " + session.getBank().getId()); //$NON-NLS-1$ //$NON-NLS-2$
		fireContextEvent(ContextListener.SESSION_ADDED);
	}

	public void removeSession( final Session session )
	{
		if ( !sessions.contains(session) )
		{
			logger.warning("Session has been already added: " + session.getSessionId()); //$NON-NLS-1$
			return;
		}

		sessions.remove(session);
		logger.info("Session is removed: " + session.getSessionId() + " / " + session.getBank().getId()); //$NON-NLS-1$ //$NON-NLS-2$

		fireContextEvent(ContextListener.SESSION_REMOVED);
	}

	public boolean hasActiveSession()
	{
		return sessions.size() > 0;
	}

	public static ImageIcon getIcon( final String imageName, final int size )
	{
		//Look for the image.
		String imgLocation = "/images/" + size + "/" + imageName + ".png"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		URL imageURL = GUIContext.class.getResource(imgLocation);
		if ( imageURL == null )
		{
			imgLocation = "/images/" + size + "/" + imageName + ".PNG"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
			imageURL = GUIContext.class.getResource(imgLocation);
		}

		ImageIcon result = null;
		if ( imageURL != null )
		{ //image found
			result = getIcon(imageURL);
		}
		else
		{ //no image found
			logger.severe("Resource not found: " + imgLocation); //$NON-NLS-1$
		}

		return result;
	}

	public static ImageIcon getImage( final String imageName )
	{
		//Look for the image.
		String imgLocation = "/images/" + imageName + ".png"; //$NON-NLS-1$ //$NON-NLS-2$
		URL imageURL = GUIContext.class.getResource(imgLocation);
		if ( imageURL == null )
		{
			imgLocation = "/images/" + imageName + ".PNG"; //$NON-NLS-1$ //$NON-NLS-2$
			imageURL = GUIContext.class.getResource(imgLocation);
		}

		ImageIcon result = null;
		if ( imageURL != null )
		{ //image found
			result = getIcon(imageURL);
		}
		else
		{ //no image found
			logger.severe("Resource not found: " + imgLocation); //$NON-NLS-1$
		}

		return result;
	}

	private static HashMap<URL, ImageIcon> iconStore = new HashMap<URL, ImageIcon>();

	public static ImageIcon getIcon( final URL url )
	{
		if ( iconStore.containsKey(url) )
			return iconStore.get(url);
		final ImageIcon icon = new ImageIcon(url);
		iconStore.put(url, icon);
		return icon;
	}

	public static String formatLongText( String longText )
	{
		final int length = longText.length();
		if ( length > 32 )
		{
			final StringBuilder builder = new StringBuilder("<html>"); //$NON-NLS-1$

			int pos = 32;
			builder.append(longText.substring(0, 32));
			while ( pos < length )
			{
				builder.append("<br/>"); //$NON-NLS-1$
				builder.append(longText.substring(pos, Math.min(length, pos + 32)));
				pos += 32;
			}
			builder.append("</html>"); //$NON-NLS-1$
			longText = builder.toString();
		}
		return longText;
	}

	public static String formatEOL( final String wrappedText )
	{
		if ( wrappedText.contains("\n") ) //$NON-NLS-1$
		{
			final StringTokenizer tokens = new StringTokenizer(wrappedText, "\n"); //$NON-NLS-1$
			final StringBuilder result = new StringBuilder("<html>"); //$NON-NLS-1$
			result.append(tokens.nextToken());
			while ( tokens.hasMoreTokens() )
			{
				result.append("<br>").append(tokens.nextToken()); //$NON-NLS-1$
			}
			result.append("</html>"); //$NON-NLS-1$
			return result.toString();
		}
		return wrappedText;
	}
}
